package com.wili.c.asm;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.c.Ca;
import com.wili.c.MiscFilter.ClsFilter;
import net.bytebuddy.jar.asm.ClassReader;
import net.bytebuddy.jar.asm.ClassVisitor;
/**
 * 
 * @author weila 2021年3月8日
 */
class FindPutField9 {
	public static void findPutField(File file, Class<?> inClass, Class<?> fieldClass, //
			Set<String> fieldSet, FieldItems fieldItemsRet) {
		ClassReader read = Asm9.newClassReader(inClass.getName());
		List<PutFieldItem> setFieldList = new ArrayList<>();
		AsmCont cont = new AsmCont(new PutFieldFilter() {
			int curLineNo = -1;

			List<FieldItem> curLineItems = new ArrayList<>();//当前行的若干属性
			/**
			 * @param isPutField 1:putField|2:getField.
			 */
			@Override
			public boolean doField(int isPutField, Class<?> curCls, String curField, int lineNo) {
				if (curLineNo == -1) {
					curLineNo = lineNo;
				} else if (curLineNo != lineNo) {//行号有变时，当清空
					curLineNo = lineNo;
					curLineItems.clear();
				}
				if (isPutField == 1) {
					if (curCls.equals(fieldClass)) {
						if (fieldSet.contains(curField)) {
							//若是为关心的属性赋值，将赋值信息追加到返回值。
							setFieldList.add(new PutFieldItem(inClass, fieldClass, curField, lineNo));
							if (lineNo == curLineNo) {
								if (fieldItemsRet.getFieldMap != null) {
									if (curLineItems.size() > 0) {
										for (FieldItem ele : curLineItems) {
											//获取赋值表达式右侧中的属性
											if (ele.cls.equals(fieldClass) && fieldSet.contains(ele.field)) {
												continue;
											}
											Set<String> getFields = fieldItemsRet.getFieldMap.get(ele.cls);
											if (getFields == null) {
												fieldItemsRet.getFieldMap.put(ele.cls, getFields = new HashSet<>());
											}
											getFields.add(ele.field);
										}
									}
								}
							}
						}
					}
				} else if (isPutField == 2) {
					//追加右侧表达式中的属性
					curLineItems.add(new FieldItem(curCls, curField));
				} else {
				}
				return true;
			}
		});
		ClassVisitor visit = new ClsVisitor(null, inClass, (ClsFilter) null, cont);
		read.accept(visit, Asm9.AsmVerion);
		if (setFieldList.size() > 0) {
			setFieldList.get(0).classFile = file;
			List<PutFieldItem> preList = fieldItemsRet.setFieldMap.get(inClass);
			if (preList == null) {
				fieldItemsRet.setFieldMap.put(inClass, setFieldList);
			} else {
				Ca.asert(fieldItemsRet.getFieldMap == null, "");
				for (PutFieldItem ele : preList) {
					for (PutFieldItem ele2 : setFieldList) {
						if (ele.equals(ele2)) {
							Ca.asert(false, ele);
						}
					}
				}
				preList.addAll(setFieldList);
			}
		}
	}
}
